home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Skunkware 5
/
Skunkware 5.iso
/
src
/
X11
/
seyon
/
SePort.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-05-03
|
22KB
|
1,127 lines
/*
* This file is part of the Seyon, Copyright (c) 1992-1993 by Muhammad M.
* Saggaf. All rights reserved.
*
* See the file COPYING (1-COPYING) or the manual page seyon(1) for a full
* statement of rights and permissions for this program.
*/
#include "config.h"
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include <X11/Intrinsic.h>
#if HAVE_TERMIOS
#include <termios.h>
#else
#if HAVE_TERMIO
#include <termio.h>
#else
#if HAVE_SGTTYB
#include <sys/ioctl.h>
#endif
#endif
#endif
#if LF_USE_DEV_NUMBERS
#include <sys/stat.h>
#ifdef SVR4
#include <sys/mkdev.h>
#else
#include <sys/sysmacros.h>
#endif /* SVR4 */
#endif /* LF_USE_DEV_NUMBERS */
#if USE_NONSTD_BAUD
#ifdef linux
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <linux/tty.h>
#endif
#endif
#include "seyon.h"
#include "SeDecl.h"
#if !defined(O_NDELAY) && defined(O_NONBLOCK)
#define O_NDELAY O_NONBLOCK
#endif
#if !defined(MAX_INPUT) && defined(_POSIX_MAX_INPUT)
#define MAX_INPUT _POSIX_MAX_INPUT
#endif
extern char TtyReadChar();
extern int TtyReadStr(),
TtyTimedReadChar(),
TtyReadLine(),
TtyTimedWaitFor(),
IoGetModemStat();
extern speed_t io_get_speed();
/*
* MDELAY is the delay in the output because (on my modem) the command would be
* ignored if sent at full speed. Change for other setups. (This setting is
* for U.S. Robotics Password Modem).
*/
#if HAVE_TERMIOS
static struct termios pmode; /* modem device control structure */
#else
#if HAVE_TERMIO
static struct termio pmode; /* modem device control structure */
#else
#if HAVE_SGTTYB
static struct sgttyb pmode;
#endif
#endif
#endif
char modem_port[REG_BUF]; /* modem port device file string */
static int mfd = -1; /* modem port file descriptor */
int baudrate = B9600; /* baud rate */
void
MdmIFlush()
{
int TtyIFlush();
TtyIFlush(mfd);
}
void
MdmOFlush()
{
int TtyOFlush();
TtyOFlush(mfd);
}
void
MdmIOFlush()
{
int TtyIOFlush();
TtyIOFlush(mfd);
}
void
send_break()
{
io_send_break(mfd);
}
void
MdmPutString(s)
char *s;
{
char c;
usleep(MDELAY);
for (; (c = *s); s++) {
if (*s == '^' && *(s + 1))
if (*(++s) == '^') c = *s;
else c = *s & 0x1f;
if (c == '~') sleep(1);
else send_tbyte(c);
usleep(MDELAY);
}
}
void
mprintf(fmt, a, b, c)
char *fmt,
*a,
*b,
*c;
{
char buf[REG_BUF];
sprintf(buf, fmt, a, b, c);
MdmPutString(buf);
}
void
get_modem_attr()
{
io_get_attr(mfd, &pmode);
baudrate = io_get_speed(&pmode);
}
void
set_modem_attr()
{
io_set_speed(&pmode, baudrate);
io_set_attr(mfd, &pmode);
}
int
get_modem_fio()
{
return fcntl(mfd, F_GETFL);
}
void
set_modem_fio(fio)
int fio;
{
fcntl(mfd, F_SETFL, fio);
}
/*---------------------------------------------------------------------------+
| MdmSaveRestoreAttr - saves or restores the modem attributes.
+---------------------------------------------------------------------------*/
int
MdmSaveRestoreAttr(action)
int action;
{
#if HAVE_TERMIOS
static struct termios savedAttr;
#else
#if HAVE_TERMIO
static struct termio savedAttr;
#else
#if HAVE_SGTTYB
static struct sgttyb savedAttr;
#endif
#endif
#endif
if (mfd == -1) return -1;
if (action == ATTR_SAVE)
return io_get_attr(mfd, &savedAttr);
else if (action == ATTR_RESTORE) {
/* Not sure how to do this with sgttyb */
#if HAVE_TERMIOS || HAVE_TERMIO
savedAttr.c_cflag &= ~HUPCL; /* don't hangup on closing */
#endif
return io_set_attr(mfd, &savedAttr);
}
return -1;
}
int
GetModemStat(newModem)
int newModem;
{
static Boolean useModemControl = True;
int retStat;
if (newModem) useModemControl = True;
if (useModemControl && (retStat = IoGetModemStat(mfd)) < 0) {
SeErrorF("Could not get control line status for device %s",
modem_port, "", "");
SeNotice("Disabling status toggles for that device");
useModemControl = False;
qres.ignoreModemDCD = True;
PopupError("errModemControl", NULL);
}
return (useModemControl ? retStat : 0);
}
int
Online()
{
return((GetModemStat(0) & MDM_DCD) ? 1 : 0);
}
void
cancel_dial(verbose)
int verbose;
{
MdmPutString(qres.dialCancelString);
MdmPurge();
if (verbose)
SeyonMessage("Canceled");
}
void
SetInitialModemAttr()
{
#if HAVE_TERMIOS || HAVE_TERMIO
pmode.c_iflag |= (IGNBRK | IGNPAR);
pmode.c_iflag &= ~(ISTRIP | BRKINT);
pmode.c_lflag = 0;
#ifdef XCLUDE
pmode.c_lflag |= XCLUDE;
#endif
pmode.c_oflag &= ~OPOST; /* transparent output */
pmode.c_cflag = baudrate | CREAD | CLOCAL;
/* this many characters satisfy reads */
pmode.c_cc[VMIN] = min(qres.modemVMin, MAX_INPUT);
pmode.c_cc[VTIME] = 1; /* or in this many tenths of a second */
#else
#if HAVE_SGTTYB
pmode.sg_flags = RAW;
#endif
#endif
xc_setflow();
set_rtscts();
}
void
set_rtscts()
{
#ifdef sco
if (qres.rtsctsFlowControl) {
pmode.c_cflag &= ~CLOCAL;
pmode.c_cflag &= ~ORTSFL;
pmode.c_cflag |= RTSFLOW | CTSFLOW;
} else {
pmode.c_cflag &= ~(ORTSFL | RTSFLOW | CTSFLOW);
}
#else /* sco */
#ifdef CRTSCTS
if (qres.rtsctsFlowControl) {
pmode.c_cflag |= CRTSCTS;
#ifdef CNORTSCTS
pmode.c_cflag &= ~CNORTSCTS;
#endif
}
else {
pmode.c_cflag &= ~CRTSCTS;
#ifdef CNORTSCTS
pmode.c_cflag |= CNORTSCTS;
#endif
}
#endif
#endif /* sco */
if (mfd != -1)
io_set_attr(mfd, &pmode);
}
void
xc_setflow()
{
if (qres.xonxoffFlowControl) {
#if HAVE_TERMIOS
pmode.c_iflag |= IXON | IXOFF;
#else
#if HAVE_TERMIO
pmode.c_iflag |= IXON | IXOFF;
pmode.c_iflag &= ~IXANY;
#else
#if HAVE_SGTOBTYB
pmode.sg_flags |= TANDEM;
#endif
#endif
#endif
}
else
#if HAVE_TERMIOS
pmode.c_iflag &= ~(IXON | IXOFF);
#else
#if HAVE_TERMIO
pmode.c_iflag &= ~(IXON | IXOFF);
pmode.c_iflag &= ~IXANY;
#else
#if HAVE_SGTTYB
pmode.sg_flags &= ~TANDEM;
#endif
#endif
#endif
if (mfd != -1)
io_set_attr(mfd, &pmode);
}
char *
mport(s) /* get/set port string */
char *s;
{
if (s != NULL)
strcpy(modem_port, s);
return (modem_port);
}
int
MdmSetGetBaud(baudIndex)
int baudIndex;
{
static char *baud[] = {"0", "300", "1200", "2400", "4800", "9600",
"19200", "38400", "57600", "115200", NULL};
long retBaud;
if (baudIndex != -1)
retBaud = mbaud(baud[baudIndex]);
else
retBaud = mbaud(NULL);
for (baudIndex = 0; baud[baudIndex]; baudIndex++)
if (atol(baud[baudIndex]) == retBaud)
return baudIndex;
return -1;
}
int
MdmSetGetCSize(bits)
int bits;
{
if (bits != -1) {
switch (bits) {
#if HAVE_TERMIOS || HAVE_TERMIO
case 5:
pmode.c_cflag &= ~CSIZE;
pmode.c_cflag |= CS5;
MdmSetGetIStrip(1);
break;
case 6:
pmode.c_cflag &= ~CSIZE;
pmode.c_cflag |= CS6;
MdmSetGetIStrip(1);
break;
case 7:
pmode.c_cflag &= ~CSIZE;
pmode.c_cflag |= CS7;
MdmSetGetIStrip(1);
break;
case 8:
pmode.c_cflag &= ~CSIZE;
pmode.c_cflag |= CS8;
MdmSetGetIStrip((int)qres.stripHighBit);
break;
#else
#if HAVE_SGTTYB
case 5:
case 6:
case 7:
pmode.sg_flags |= CBREAK;
pmode.sg_flags &= ~RAW;
MdmSetGetIStrip(0);
break;
case 8:
pmode.sg_flags |= RAW;
pmode.sg_flags &= ~CBREAK;
MdmSetGetIStrip(0);
break;
#endif
#endif
default:
SeErrorF("invalid number of bits: %d", bits, "", "");
return -1;
}
/* io_set_attr is called in MdmSetGetIStrip */
}
if (mfd != -1)
io_get_attr(mfd, &pmode);
#if HAVE_TERMIOS || HAVE_TERMIO
switch (pmode.c_cflag & CSIZE) {
case CS5:
return 5;
case CS6:
return 6;
case CS7:
return 7;
case CS8:
return 8;
default:
SeError("Consistency error in number of bits");
return -1;
#else
#if HAVE_SGTTYB
switch (pmode.sg_flags & CBREAK) {
case 0:
return 8;
default:
return 7;
#endif
#endif
}
}
int
MdmSetGetParity(parity)
int parity;
{
if (parity != -1) {
switch (parity) {
#if HAVE_TERMIOS || HAVE_TERMIO
case 0:
pmode.c_cflag &= ~PARENB;
break;
case 1:
pmode.c_cflag |= (PARENB | PARODD);
break;
case 2:
pmode.c_cflag |= PARENB;
pmode.c_cflag &= ~PARODD;
break;
#else
#if HAVE_SGTTYB
case 0:
pmode.sg_flags &= ~ANYP;
break;
case 1:
pmode.sg_flags |= ODDP;
pmode.sg_flags &= ~EVENP;
break;
case 2:
pmode.sg_flags |= EVENP;
pmode.sg_flags &= ~ODDP;
break;
#endif
#endif
default:
SeErrorF("Invalid parity: %d", parity, "", "");
return -1;
}
if (mfd != -1)
io_set_attr(mfd, &pmode);
}
if (mfd != -1)
io_get_attr(mfd, &pmode);
#if HAVE_TERMIOS || HAVE_TERMIO
if (!(pmode.c_cflag & PARENB))
return 0;
else if (pmode.c_cflag & PARODD)
return 1;
else
return 2;
#else
#if HAVE_SGTTYB
switch (pmode.sg_flags & ANYP) {
case ODDP:
return 1;
case EVENP:
return 2;
default:
return 0;
}
#endif
#endif
}
int
MdmSetGetIStrip(flag)
int flag;
{
#if HAVE_TERMIOS || HAVE_TERMIO
if (flag != -1) {
if (flag)
pmode.c_iflag |= ISTRIP;
else
pmode.c_iflag &= ~ISTRIP;
if (mfd != -1)
io_set_attr(mfd, &pmode);
}
if (mfd != -1)
io_get_attr(mfd, &pmode);
if (pmode.c_iflag & ISTRIP)
return 1;
else
return 0;
#else
#if !HAVE_SGTTYB
if (mfd != -1)
io_set_attr(mfd, &pmode);
return 0;
#endif
#endif
}
int
MdmSetGetStopBits(bits)
int bits;
{
#if HAVE_TERMIOS || HAVE_TERMIO
if (bits != -1) {
switch (bits) {
case 1:
pmode.c_cflag &= ~CSTOPB;
break;
case 2:
pmode.c_cflag |= CSTOPB;
break;
default:
SeErrorF("invalid number of stop bits: %d", bits, "", "");
return -1;
}
if (mfd != -1)
io_set_attr(mfd, &pmode);
}
if (mfd != -1)
io_get_attr(mfd, &pmode);
if (pmode.c_cflag & CSTOPB)
return 2;
else
return 1;
#else
#if !HAVE_SGTTYB
if (mfd != -1)
io_set_attr(mfd, &pmode);
return 1;
#endif
#endif
}
/*
* Get/set the baud rate of the modem port. If the port hasn't been opened
* yet, just store in pmode for mopen() to use when it opens the port.
*/
long
mbaud(s)
char *s;
{
#if USE_NONSTD_BAUD
#ifdef linux
static struct serial_struct ser_io;
if (ioctl(mfd, TIOCGSERIAL, &ser_io) < 0) {
SePError("Could not get linux serial info");
return -1;
}
#endif
#endif
if (s != NULL) {
/* this gives a more limited, realistic */
switch (atol(s)) { /* range than in sgtty.h */
case 300:
baudrate = B300;
break;
case 1200:
baudrate = B1200;
break;
case 2400:
baudrate = B2400;
break;
case 4800:
baudrate = B4800;
break;
case 9600:
baudrate = B9600;
break;
case 19200:
baudrate = B19200;
break;
case 38400:
baudrate = B38400;
#if USE_NONSTD_BAUD
#ifdef linux
ser_io.flags &= ~ASYNC_SPD_MASK;
#endif
#endif
break;
#if USE_NONSTD_BAUD
#ifdef linux
case 57600:
baudrate = B38400;
ser_io.flags &= ~ASYNC_SPD_MASK;
ser_io.flags |= ASYNC_SPD_HI;
break;
case 115200:
baudrate = B38400;
ser_io.flags &= ~ASYNC_SPD_MASK;
ser_io.flags |= ASYNC_SPD_VHI;
break;
#endif
#endif
default:
return (-1);
}
io_set_speed(&pmode, baudrate);
if (mfd != -1) {
io_set_attr(mfd, &pmode);
#if USE_NONSTD_BAUD
#ifdef linux
if (baudrate == B38400)
if (ioctl(mfd, TIOCSSERIAL, &ser_io) < 0) {
SePError("Could not set linux serial info");
return -1;
}
#endif
#endif
}
}
if (mfd != -1)
io_get_attr(mfd, &pmode);
switch (io_get_speed(&pmode)) {
case B300:
return (300);
case B1200:
return (1200);
case B2400:
return (2400);
case B4800:
return (4800);
case B9600:
return (9600);
case B19200:
return (19200);
case B38400:
#if USE_NONSTD_BAUD
#ifdef linux
if (mfd != -1)
if (ioctl(mfd, TIOCGSERIAL, &ser_io) < 0) {
SePError("Could not get linux serial info");
return -1;
}
if ((ser_io.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
return 115200;
else if ((ser_io.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
return 57600;
else
#endif
#endif
return 38400;
}
SeError("Consistency error in baud rate");
return -1;
}
/*
* The following routine is used to hang up the modem. This is accomplished
* by setting the baud rate to 0. According to my documentation on termio,
* setting the baud rate to zero will result in DTR not being asserted. This
* hangs up some (most?) modems. If not, the second part of the routine
* sends the Hayes modem "escape" and then a hangup command.
*/
void
MdmHangup()
{
int terminalWasActive;
#ifdef sco
int old_cflag;
#endif
if (mfd == -1) return;
terminalWasActive = SuspContTerminal(TERM_SUSPEND);
if (qres.hangupViaDTR) {
#ifdef sco
old_cflag = pmode.c_cflag;
#endif
io_set_speed(&pmode, B0); /* set baud 0 (drop DTR) */
io_set_attr(mfd, &pmode);
sleep(1); /* wait a second */
io_set_speed(&pmode, baudrate); /* reset baud rate */
#ifdef sco
pmode.c_cflag |= CLOCAL;
#endif
io_set_attr(mfd, &pmode);
#ifdef sco
pmode.c_cflag = old_cflag;
io_set_attr(mfd, &pmode);
#endif
}
else { /* use Hayes command */
sleep(2); /* allow for "escape guard time" */
MdmPutString(qres.modemAttentionString); /* send modem escape command */
sleep(3); /* more "escape guard time" */
MdmPutString(qres.modemHangupString); /* send hangup command */
}
MdmPurge();
if (terminalWasActive) SuspContTerminal(TERM_CONTINUE);
UpdateStatusBox(NULL);
}
/*
* Opens the modem port and configures it. Returns 0 for success or -1 on
* error.
*/
int
OpenModem(modem)
String modem;
{
int LockModem(),
UnlockModem();
void MdmIOFlush();
int oldFlags;
if (modem == NULL || modem[0] == '\0') return ERR_MDM_NOMODEM;
if (LockModem(modem)) return ERR_MDM_LOCKED;
/* Need O_NDELAY to get the file open before we have carrier */
if ((mfd = open(modem, O_RDWR | O_NDELAY)) < 0)
{UnlockModem(modem); return ERR_MDM_OPENFAILED;}
/* Now, we must reset the O_NDELAY mode so that read() works correctly */
if (((oldFlags = fcntl(mfd, F_GETFL, 0)) == -1) ||
(fcntl(mfd, F_SETFL, oldFlags & ~O_NDELAY) == -1))
{UnlockModem(modem); return ERR_MDM_RESETFLAGSFAILED;}
#if HAVE_SGTTYB
if (ioctl(mfd, TIOCEXCL) < 0)
SePError("exclusive-use");
#endif
mport(modem);
MdmIOFlush();
MdmSaveRestoreAttr(ATTR_SAVE);
SetInitialModemAttr();
io_set_attr(mfd, &pmode);
GetModemStat(1);
if (mbaud(qres.defaultBPS) == -1)
se_warningf("invalid default BPS value: %s", qres.defaultBPS, "", "");
if (MdmSetGetCSize(qres.defaultBits) < 0)
se_warningf("invalid default number of bits: %s", qres.defaultBits,
"", "");
if (MdmSetGetParity(qres.defaultParity) < 0)
se_warningf("invalid default parity value: %s", qres.defaultParity,
"", "");
if (MdmSetGetStopBits(qres.defaultStopBits) < 0)
se_warningf("invalid default number of stop bits: %s",
qres.defaultStopBits, "", "");
return 0;
}
void
ShowOpenModemErrMsg(modemName, retStatus)
String modemName;
int retStatus;
{
switch(retStatus) {
case ERR_MDM_NOMODEM:
SeError("No Modem Specified");
break;
case ERR_MDM_LOCKED:
SeError(FmtString("Modem ``%s'' is Locked", modemName, "", ""));
break;
case ERR_MDM_OPENFAILED:
SePError(FmtString("Unable to Open Modem ``%s''", modemName, "", ""));
break;
case ERR_MDM_RESETFLAGSFAILED:
SePError(FmtString("Unable to Reset Flags for Modem ``%s''",
modemName, "", ""));
break;
default:
SeError(FmtString("Unknown Error While Openeong Modem ``%s''",
modemName, "", ""));
break;
}
}
int
CloseModem()
{
if (mfd == -1) return -1;
MdmSaveRestoreAttr(ATTR_RESTORE);
close(mfd);
return 0;
}
/*
* Attach standard input and output to the modem port. This only gets called
* after a fork by the child process; which then exec's a program that uses
* standard i/o for some data transfer protocol. (To put this here is
* actually a kludge, but I wanted to keep the modem-specific stuff in a
* black box.)
*/
void
mattach()
{
extern int dup2();
/*
* attach standard i/o to port
*/
dup2(mfd, 0); /* close local stdin and connect to port */
dup2(mfd, 1); /* close local stdout and connect to port */
close(mfd); /* close the old port descriptor */
}
/* ------------------------------------------------------------
* Routines to read from the modem.
*/
/*
* MdmReadStr: reads a bunch of characters from the modem.
*/
int
MdmReadStr(buf)
char *buf;
{
return TtyReadStr(mfd, buf);
}
/*
* MdmReadChar: reads one character from the modem.
*/
char
MdmReadChar(readChar)
char *readChar;
{
return TtyReadChar(mfd, readChar);
}
int
MdmTimedReadChar(readChar, expireTime)
char *readChar;
int expireTime;
{
return TtyTimedReadChar(mfd, readChar, expireTime);
}
/*
* MdmReadLine: reads one line from the modem.
*/
int
MdmReadLine(buf)
char *buf;
{
return TtyReadLine(mfd, buf);
}
int
MdmTimedWaitFor(expectedString, waitTime)
char *expectedString;
int waitTime;
{
return TtyTimedWaitFor(mfd, expectedString, waitTime);
}
/*
* MdmPurge: throws away all incoming characters until no more are sent.
*/
void
MdmPurge()
{
char c;
while (MdmTimedReadChar(&c, 1) >= 0);
}
#ifdef retired
int
readbyte(seconds)
int seconds;
{
return trminp(mfd, seconds);
}
#endif
/*
* Output a byte to the modem port. All data sent to the modem
* is output through this routine.
*/
void
sendbyte(ch)
int ch;
{
char c = ch & 0xff;
if (write(mfd, &c, 1) < 0)
SePError("character write");
}
void
sendf_slowly(format, a, b, c)
char *format,
*a,
*b,
*c;
{
char buffer[SM_BUF];
sprintf(buffer, format, a, b, c);
send_slowly(buffer);
}
void
send_slowly(s)
char *s;
{
while (*s) {
sendbyte(*s++);
/*
* avoid busy waiting by using usleep if available. adjust MDELAY if
* you're having trouble
*/
usleep(MDELAY);
}
}
/*
* lock_tty() returns non-zero if the lock file exists (prevents Seyon from
* running).
*
* unlock_tty() deletes the lock file.
*
* Simple, eh?
*/
char lckf[SM_BUF];
char ltmp[SM_BUF];
pid_t lockPid;
int
LockModem(modem)
String modem;
{
strcpy(modem_port, modem);
return lock_tty();
}
int
UnlockModem(modem)
String modem;
{
unlock_tty();
return 0;
}
int
lock_tty()
{
int lfd;
pid_t pid,
lckpid;
char *modemname;
#if LF_USE_ASCII_PID
char pidstr[20],
lckpidstr[20];
int nb;
#endif
#if LF_LOWERCASE
char final;
#endif
#if LF_USE_DEV_NUMBERS
struct stat mbuf;
#endif
/* Get our PID, and initialize the filename strings */
pid = getpid();
#if !LF_USE_DEV_NUMBERS
modemname = strrchr(modem_port, '/');
sprintf(lckf, "%s/%s%s", LF_PATH, LF_PREFIX,
(modemname ? (modemname + 1) : modem_port));
#if LF_LOWERCASE
final = lckf[strlen(lckf)-1];
final = tolower(final);
lckf[strlen(lckf)-1] = final;
#endif
#else
if(stat(modem_port, &mbuf) < 0) {
SePErrorF("could not stat modem port %s", modem_port, "", "");
return -1;
}
sprintf(lckf,"%s/%s%03u.%03u.%03u", LF_PATH, LF_PREFIX, major(mbuf.st_dev),
major(mbuf.st_rdev), minor(mbuf.st_rdev));
#endif /* LF_USE_DEV_NUMBERS */
sprintf(ltmp, "%s/%s%d", LF_PATH, "LTMP.", pid);
/* Create the LTMP.<pid> file and scribble our PID in it */
unlink(ltmp);
if ((lfd = creat(ltmp, 0644)) == -1) {
SePErrorF("Could not create temporary lock file %s", ltmp, "", "");
return -1;
}
#if LF_USE_ASCII_PID
sprintf(pidstr, "%10d\n", pid);
write(lfd, pidstr, 11);
#else
write(lfd, (char*)&pid, sizeof(pid));
#endif
close(lfd);
/*
* Attempt to link directly - if it works, we're done.
*/
relink:
if (link(ltmp, lckf) == 0) {
unlink(ltmp);
lockPid = pid;
return 0;
}
/*
* Oh brother, there's a LCK..* file already; we must now expend effort to
* learn if it's stale or not.
*/
if ((lfd = open(lckf, O_RDONLY)) != -1) {
#if LF_USE_ASCII_PID
for (nb = 0; nb < 20 && read(lfd, lckpidstr + nb, sizeof(char)); nb++);
if (nb) {
lckpid = atol(lckpidstr);
#else
if (read(lfd, (char *)&lckpid, sizeof(lckpid)) == sizeof(lckpid)) {
#endif
lockPid = (pid_t) lckpid;
if (kill(lckpid, 0) == 0) {
SeErrorF("Device %s is locked by process %d", modem_port, lckpid, "");
unlink(ltmp);
return -1;
}
}
}
/*
* The LCK..* file was stale. Remove and retry.
*/
if (unlink(lckf)) {
SePErrorF("Unable to unlink stale lock file \"%s\"", lckf, "", "");
unlink(ltmp);
return -1;
}
goto relink;
/* NOTREACHED */
}
void
unlock_tty()
{
/* Don't remove the lock file unless it's the one we created */
if (getpid() == lockPid)
unlink(lckf);
}